package com.threeox.commonlibrary.ui.view.navigationview;

import com.threeox.commonlibrary.R;
import com.threeox.commonlibrary.ui.view.engineview.model.ModelBaseView;
import com.threeox.commonlibrary.ui.view.pullrefresh.base.PullToRefreshLayout;
import com.threeox.utillibrary.util.LogUtils;

import android.annotation.SuppressLint;
import android.content.Context;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.OverScroller;
import android.widget.ScrollView;

@SuppressLint("NewApi")
public class StickyNavLayout extends LinearLayout {

    private View mTop;
    private View mNav;
    private ViewPager mViewPager;

    private int mTopViewHeight;
    private ViewGroup mInnerScrollView;
    private boolean isTopHidden = false;

    private OverScroller mScroller;
    private VelocityTracker mVelocityTracker;
    private int mTouchSlop;
    private int mMaximumVelocity, mMinimumVelocity;
    private float mLastY;
    // private float mDownY = -1;
    private boolean mDragging;
    private boolean isInControl = false;
    private boolean isHideTop = false;

    public StickyNavLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        setOrientation(LinearLayout.VERTICAL);

        mScroller = new OverScroller(context);
        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
        mMaximumVelocity = ViewConfiguration.get(context)
                .getScaledMaximumFlingVelocity();
        mMinimumVelocity = ViewConfiguration.get(context)
                .getScaledMinimumFlingVelocity();

    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        mTop = findViewById(R.id.id_stickynavlayout_topview);
        mNav = findViewById(R.id.id_viewpage_indicator);
        View view = findViewById(R.id.id_viewpager_layout);
        if (!(view instanceof ViewPager)) {
            throw new RuntimeException(
                    "id_stickynavlayout_viewpager show used by ViewPager !");
        }
        mViewPager = (ViewPager) view;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        ViewGroup.LayoutParams params = mViewPager.getLayoutParams();
        params.height = getMeasuredHeight() - mNav.getMeasuredHeight();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mTopViewHeight = mTop.getMeasuredHeight();
        if (isHideTop) {
            scrollTo();
        }
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        // if (mDownY == -1) {
        // mDownY = ev.getY();
        // }
        int action = ev.getAction();
        float y = ev.getY();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                // mDownY = y;
                mLastY = y;
                break;
            case MotionEvent.ACTION_MOVE:
                float dy = y - mLastY;
                getCurrentScrollView();
                if (mInnerScrollView instanceof ScrollView) {
                    if (mInnerScrollView.getScrollY() == 0 && isTopHidden && dy > 0
                            && !isInControl) {
                        isInControl = true;
                        ev.setAction(MotionEvent.ACTION_CANCEL);
                        MotionEvent ev2 = MotionEvent.obtain(ev);
                        dispatchTouchEvent(ev);
                        ev2.setAction(MotionEvent.ACTION_DOWN);
                        return dispatchTouchEvent(ev2);
                    }
                } else if (mInnerScrollView instanceof ListView) {
                    ListView lv = (ListView) mInnerScrollView;
                    View c = lv.getChildAt(lv.getFirstVisiblePosition());
                    if (lv.getCount() > 0) {
                        if (!isInControl && c != null && c.getTop() == 0
                                && isTopHidden && dy > 0) {
                            isInControl = true;
                            ev.setAction(MotionEvent.ACTION_CANCEL);
                            MotionEvent ev2 = MotionEvent.obtain(ev);
                            dispatchTouchEvent(ev);
                            ev2.setAction(MotionEvent.ACTION_DOWN);
                            return dispatchTouchEvent(ev2);
                        }
                    } else {
                        if (!isInControl && isTopHidden && dy > 0) {
                            isInControl = true;
                            ev.setAction(MotionEvent.ACTION_CANCEL);
                            MotionEvent ev2 = MotionEvent.obtain(ev);
                            dispatchTouchEvent(ev);
                            ev2.setAction(MotionEvent.ACTION_DOWN);
                            return dispatchTouchEvent(ev2);
                        }
                    }
                } else if (mInnerScrollView instanceof PullToRefreshLayout) {
                    LogUtils.e("isTopHidden:" + isTopHidden + "-->getScrollY" + getScrollY() + "-->height:" + mTopViewHeight);
                    PullToRefreshLayout layout = (PullToRefreshLayout) mInnerScrollView;
                    if (layout.isPullDown() && isTopHidden && dy > 0
                            && !isInControl) {
                        isInControl = true;
                        ev.setAction(MotionEvent.ACTION_CANCEL);
                        MotionEvent ev2 = MotionEvent.obtain(ev);
                        dispatchTouchEvent(ev);
                        ev2.setAction(MotionEvent.ACTION_DOWN);
                        return dispatchTouchEvent(ev2);
                    }
                } else if (mInnerScrollView instanceof ModelBaseView) {

                }
                // else if (mInnerScrollView instanceof RecyclerView) {
                //
                // RecyclerView rv = (RecyclerView) mInnerScrollView;
                //
                // if (!isInControl
                // && android.support.v4.view.ViewCompat
                // .canScrollVertically(rv, -1) && isTopHidden
                // && dy > 0) {
                // isInControl = true;
                // ev.setAction(MotionEvent.ACTION_CANCEL);
                // MotionEvent ev2 = MotionEvent.obtain(ev);
                // dispatchTouchEvent(ev);
                // ev2.setAction(MotionEvent.ACTION_DOWN);
                // return dispatchTouchEvent(ev2);
                // }
                // }
                break;
        }
        return super.dispatchTouchEvent(ev);
    }

    /**
     *
     */
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        final int action = ev.getAction();
        float y = ev.getY();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                mLastY = y;
                break;
            case MotionEvent.ACTION_MOVE:
                float dy = y - mLastY;
                getCurrentScrollView();
                if (Math.abs(dy) > mTouchSlop) {
                    mDragging = true;
                    if (mInnerScrollView instanceof ScrollView) {
                        // 如果topView没有隐藏
                        // 或sc的scrollY = 0 && topView隐藏 && 下拉，则拦截
                        if (!isTopHidden
                                || (mInnerScrollView.getScrollY() == 0
                                && isTopHidden && dy > 0)) {
                            initVelocityTrackerIfNotExists();
                            mVelocityTracker.addMovement(ev);
                            mLastY = y;
                            return true;
                        }
                    } else if (mInnerScrollView instanceof ListView) {
                        ListView lv = (ListView) mInnerScrollView;
                        View c = lv.getChildAt(lv.getFirstVisiblePosition());
                        if (lv.getCount() > 0) {
                            if (!isTopHidden || //
                                    (c != null //
                                            && c.getTop() == 0//
                                            && isTopHidden && dy > 0)) {
                                initVelocityTrackerIfNotExists();
                                mVelocityTracker.addMovement(ev);
                                mLastY = y;
                                return true;
                            }
                        } else {
                            if (!isTopHidden || (isTopHidden && dy > 0)) {
                                initVelocityTrackerIfNotExists();
                                mVelocityTracker.addMovement(ev);
                                mLastY = y;
                                return true;
                            }
                        }
                    } else if (mInnerScrollView instanceof PullToRefreshLayout) {
                        LogUtils.e("onInterceptTouchEvent:isTopHidden:"
                                + isTopHidden);
                        PullToRefreshLayout layout = (PullToRefreshLayout) mInnerScrollView;
                        if (!isTopHidden
                                || (layout.isPullDown() && isTopHidden && dy > 0)) {
                            initVelocityTrackerIfNotExists();
                            mVelocityTracker.addMovement(ev);
                            mLastY = y;
                            return true;
                        }
                    } else if (mInnerScrollView instanceof ModelBaseView) {

                    }
                    // else if (mInnerScrollView instanceof RecyclerView) {
                    // RecyclerView rv = (RecyclerView) mInnerScrollView;
                    // if (!isTopHidden
                    // || (!android.support.v4.view.ViewCompat
                    // .canScrollVertically(rv, -1) && isTopHidden && dy > 0)) {
                    // initVelocityTrackerIfNotExists();
                    // mVelocityTracker.addMovement(ev);
                    // mLastY = y;
                    // return true;
                    // }
                    // }
                }
                break;
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                // mDownY = -1;
                mDragging = false;
                recycleVelocityTracker();
                break;
        }
        return super.onInterceptTouchEvent(ev);
    }

    private void getCurrentScrollView() {
        int currentItem = mViewPager.getCurrentItem();
        PagerAdapter pagerAdapter = mViewPager.getAdapter();
        if (pagerAdapter instanceof FragmentPagerAdapter) {
            FragmentPagerAdapter fadapter = (FragmentPagerAdapter) pagerAdapter;
            Fragment item = (Fragment) fadapter.instantiateItem(mViewPager, currentItem);
            mInnerScrollView = (item.getView().findViewById(R.id.id_refresh_listview));
            if (mInnerScrollView == null) {
                mInnerScrollView = (item.getView().findViewById(R.id.id_pulltorefreshlayout));
            }
            if (mInnerScrollView == null) {
                mInnerScrollView = (item.getView().findViewById(R.id.id_model_base_scroll));
            }
        } else if (pagerAdapter instanceof FragmentStatePagerAdapter) {
            FragmentStatePagerAdapter fsAdapter = (FragmentStatePagerAdapter) pagerAdapter;
            Fragment item = (Fragment) fsAdapter.instantiateItem(mViewPager, currentItem);
            mInnerScrollView = (item.getView().findViewById(R.id.id_refresh_listview));
            if (mInnerScrollView == null) {
                mInnerScrollView = (item.getView().findViewById(R.id.id_pulltorefreshlayout));
            }
            if (mInnerScrollView == null) {
                mInnerScrollView = (item.getView().findViewById(R.id.id_model_base_scroll));
            }
        } else {
            Object item = pagerAdapter.instantiateItem(mViewPager, currentItem);
            if (item != null) {
                if (item instanceof View) {
                    View view = (View) item;
                    mInnerScrollView = view.findViewById(R.id.id_refresh_listview);
                    if (mInnerScrollView == null) {
                        mInnerScrollView = view.findViewById(R.id.id_pulltorefreshlayout);
                    }
                    if (mInnerScrollView == null) {
                        mInnerScrollView = view.findViewById(R.id.id_model_base_scroll);
                    }
                }
            }

        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        initVelocityTrackerIfNotExists();
        mVelocityTracker.addMovement(event);
        int action = event.getAction();
        float y = event.getY();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                if (!mScroller.isFinished()) {
                    mScroller.abortAnimation();
                }
                mLastY = y;
                return true;
            case MotionEvent.ACTION_MOVE:
                float dy = y - mLastY;
                Log.e("TAG", "dy = " + dy + " , y = " + y + " , mLastY = " + mLastY);
                if (!mDragging && Math.abs(dy) > mTouchSlop) {
                    mDragging = true;
                }
                if (mDragging) {
                    scrollBy(0, (int) -dy);
                    // 如果topView隐藏，且上滑动时，则改变当前事件为ACTION_DOWN
                    if (getScrollY() == mTopViewHeight && dy < 0) {
                        event.setAction(MotionEvent.ACTION_DOWN);
                        dispatchTouchEvent(event);
                        isInControl = false;
                    }
                }
                mLastY = y;
                break;
            case MotionEvent.ACTION_CANCEL:
                mDragging = false;
                recycleVelocityTracker();
                if (!mScroller.isFinished()) {
                    mScroller.abortAnimation();
                }
                break;
            case MotionEvent.ACTION_UP:
                mDragging = false;
                mVelocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
                int velocityY = (int) mVelocityTracker.getYVelocity();
                if (Math.abs(velocityY) > mMinimumVelocity) {
                    fling(-velocityY);
                }
                recycleVelocityTracker();
                break;
        }

        return super.onTouchEvent(event);
    }

    public void fling(int velocityY) {
        mScroller.fling(0, getScrollY(), 0, velocityY, 0, 0, 0, mTopViewHeight);
        invalidate();
    }

    @Override
    public void scrollTo(int x, int y) {
        if (y < 0) {
            y = 0;
        }
        if (y > mTopViewHeight) {
            y = mTopViewHeight;
        }
        if (y != getScrollY()) {
            super.scrollTo(x, y);
        }

        isTopHidden = getScrollY() == mTopViewHeight;

    }

    public void scrollTo() {
        scrollTo(0, mTopViewHeight);
        invalidate();
    }

    @Override
    public void computeScroll() {
        if (mScroller.computeScrollOffset()) {
            scrollTo(0, mScroller.getCurrY());
            invalidate();
        }
    }

    private void initVelocityTrackerIfNotExists() {
        if (mVelocityTracker == null) {
            mVelocityTracker = VelocityTracker.obtain();
        }
    }

    private void recycleVelocityTracker() {
        if (mVelocityTracker != null) {
            mVelocityTracker.recycle();
            mVelocityTracker = null;
        }
    }

    public void setHideTop(boolean isHideTop) {
        this.isHideTop = isHideTop;
    }

}
